// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//

#include <gtest/gtest.h>
#include <climits>
#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cantor/parser/parser.h>

int main(int argc, char *argv[]) {
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

namespace cantor::parser {
    TEST(test_parser, case_create_view) {
        cantor::parser::SqlParser parser1;
        std::string sql1 = "create or replace view aa (a,b,c,d) as select i,j,k,l from t1";
        parser1.parse(sql1);
        printf("errormsg: %d, %s\n", parser1.error, parser1.syntax_err_str.c_str());
        EXPECT_EQ(1, parser1.result.size());
        if (parser1.result.size() != 1) {
            return;
        }
        CreateViewStmt *stmt1 = (CreateViewStmt *) parser1.result[0];
        EXPECT_EQ(cantor::pb::ast::STMT_CREATE_VIEW, stmt1->stmt_type);
        EXPECT_EQ(true, stmt1->or_replace);
        EXPECT_EQ(false, ((cantor::parser::SelectStmt*)stmt1->view_select_stmt)->fields[0]->wild_card);
        std::cout << stmt1->to_json() << std::endl;

        cantor::parser::SqlParser parser2;
        std::string sql2 = "create view aa(a,b,c,d) as select * from t1";
        parser2.parse(sql2);
        printf("errormsg: %d, %s\n", parser2.error, parser2.syntax_err_str.c_str());
        EXPECT_EQ(1, parser2.result.size());
        if (parser2.result.size() != 1) {
            return;
        }
        EXPECT_EQ(cantor::pb::ast::STMT_CREATE_VIEW, parser2.result[0]->stmt_type);
        CreateViewStmt *stmt2 = (CreateViewStmt *) parser2.result[0];
        EXPECT_EQ(false, stmt2->or_replace);
        std::ostringstream os;
        cantor::parser::SelectStmt *view_select_stmt = (cantor::parser::SelectStmt *) stmt2->view_select_stmt;
        view_select_stmt->to_stream(os);
        EXPECT_EQ("SELECT * FROM t1", os.str());
        EXPECT_EQ(true, view_select_stmt->fields[0]->wild_card);

        std::ostringstream view_name_os;
        stmt2->view_name->to_stream(view_name_os);
        EXPECT_EQ("aa", view_name_os.str());
        EXPECT_EQ(4, stmt2->column_names.size());
        EXPECT_EQ(stmt2->column_names[0]->column_name.to_string(), "a");
        EXPECT_EQ(stmt2->column_names[1]->column_name.to_string(), "b");
        EXPECT_EQ(stmt2->column_names[2]->column_name.to_string(), "c");
        EXPECT_EQ(stmt2->column_names[3]->column_name.to_string(), "d");
        std::cout << stmt2->to_json() << std::endl;
    }


    TEST(test_parser, errmsg) {
        {
            cantor::parser::SqlParser parser;
            std::string sql = "creat type t1.my_struct AS struct(abc int, bcd int[])";
            parser.parse(sql);
            std::cout << parser.syntax_err_str << std::endl;
        }
    }
} // namespace cantor::parser
